package com.mentaleye.biz.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.mentaleye.bean.StudentDisciplineRecordBean;
import com.mentaleye.biz.StudentDisciplineRecordBiz;
import com.mentaleye.dal.model.StudentAttendanceRecord;
import com.mentaleye.dal.model.StudentDiscipline;
import com.mentaleye.dal.model.StudentDisciplineDataRecord;
import com.mentaleye.dal.model.StudentDisciplineRecord;
import com.mentaleye.enums.DictionaryEnums;
import com.mentaleye.enums.DisciplineEnums;
import com.mentaleye.service.StudentAttendanceRecordService;
import com.mentaleye.service.StudentDisciplineDataRecordService;
import com.mentaleye.service.StudentDisciplineRecordService;
import com.mentaleye.service.StudentDisciplineService;
import com.mentaleye.util.CommonPage;
import com.mentaleye.util.CommonResult;
import com.mentaleye.util.DateFormatter;
import com.mentaleye.util.DisciplineDataUtil;
import com.mentaleye.util.ObjectUtil;

@Service
public class StudentDisciplineRecordBizImpl implements StudentDisciplineRecordBiz {

	private static Logger logger = Logger.getLogger(StudentDisciplineRecordBiz.class);

	@Autowired
	private StudentAttendanceRecordService attendanceRecordService;

	@Autowired
	private StudentDisciplineService disciplineService;
	
	@Autowired
	private StudentDisciplineRecordService disciplineRecordService;

	@Autowired
	private StudentDisciplineDataRecordService disciplineDataRecordService;

	@Override
	public CommonResult insertRecord(StudentDisciplineRecordBean disciplineRecordBean) {
		CommonResult result = new CommonResult();
		StudentDisciplineDataRecord dataRecord = null;
		String writeTimeString = disciplineRecordBean.getWriteTimeString();
		Date writeTime = DateFormatter.parse(writeTimeString, "yyyy-MM-dd");
		disciplineRecordBean.setWriteTime(writeTime);

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("studentId", disciplineRecordBean.getStudentId());
		map.put("writeTime", writeTime);
		try {
			StudentDisciplineRecord disciplineRecord = (StudentDisciplineRecord) ObjectUtil
					.transfer(disciplineRecordBean, StudentDisciplineRecord.class);
			if (this.disciplineRecordService.insertRecord(disciplineRecord)) {
				dataRecord = this.disciplineDataRecordService.getRecordBySelective(map);
				updateAttendanceRecordForInsert(dataRecord);
				result.setIsSuccess(true);
				result.setResultMsg("添加成功！");
			} else {
				result.setResultMsg("添加失败！");
			}
		} catch (Exception e) {
			result.setResultMsg("添加异常！");
			logger.error("学生违纪信息添加异常！", e);
		}
		return result;
	}

	@SuppressWarnings("unchecked")
	@Override
	public CommonResult insertByList(List<StudentDisciplineRecordBean> beanList) {
		CommonResult result = new CommonResult();
		List<StudentDisciplineRecord> recordList = null;
		try {
			for (StudentDisciplineRecordBean bean : beanList) {
				bean.setWriteTime(DateFormatter.parse(bean.getWriteTimeString(), "yyyy-MM-dd"));
			}
			recordList = ObjectUtil.transferList(beanList, StudentDisciplineRecord.class);
			if (this.disciplineRecordService.insertByList(recordList)) {
				result.setIsSuccess(true);
				result.setResultMsg("添加成功！");
			} else {
				result.setResultMsg("添加失败！");
			}
		} catch (Exception e) {
			result.setResultMsg("添加异常！");
			logger.error("学生违纪信息添加异常！", e);
		}
		return result;
	}

	@Override
	public CommonResult updateRecord(StudentDisciplineRecordBean disciplineRecordBean) {
		CommonResult result = new CommonResult();
		StudentDisciplineDataRecord oldDataRecord = null;
		StudentDisciplineDataRecord newDataRecord = null;
		String writeTimeString = disciplineRecordBean.getWriteTimeString();
		Date writeTime = DateFormatter.parse(writeTimeString, "yyyy-MM-dd");
		disciplineRecordBean.setWriteTime(writeTime);

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("studentId", disciplineRecordBean.getStudentId());
		map.put("writeTime", writeTime);
		try {
			oldDataRecord = this.disciplineDataRecordService.getRecordBySelective(map);
			StudentDisciplineRecord disciplineRecord = (StudentDisciplineRecord) ObjectUtil
					.transfer(disciplineRecordBean, StudentDisciplineRecord.class);
			if (this.disciplineRecordService.updateRecord(disciplineRecord)) {
				newDataRecord = this.disciplineDataRecordService.getRecordBySelective(map);
				updateAttendanceRecordForUpdate(oldDataRecord, newDataRecord);
				result.setIsSuccess(true);
				result.setResultMsg("更新成功！");
			} else {
				result.setResultMsg("更新失败！");
			}
		} catch (Exception e) {
			result.setResultMsg("更新异常！");
			logger.error("学生违纪信息更新异常！", e);
		}
		return result;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<StudentDisciplineRecordBean> getBeanList() {
		List<StudentDisciplineRecordBean> beanList = null;
		try {
			beanList = ObjectUtil.transferList(this.disciplineRecordService.getList(),
					StudentDisciplineRecordBean.class);
		} catch (Exception e) {
			logger.error("学生违纪信息查询异常！", e);
		}
		return beanList;
	}

	@Override
	public List<StudentDisciplineRecord> getList() {
		List<StudentDisciplineRecord> recordList = null;
		try {
			recordList = this.disciplineRecordService.getList();
		} catch (Exception e) {
			logger.error("学生违纪信息查询异常！", e);
		}
		return recordList;
	}

	@Override
	public Map<String, Object> getMapByKey(int id) {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("recordId", id);
		try {
			resultMap = this.disciplineRecordService.getMapByMap(paramMap);
		} catch (Exception e) {
			logger.error("读取学生违纪信息异常！", e);
		}
		return resultMap;
	}

	@Override
	public void getListByPage(CommonPage page) {
		List<Map<String, Object>> recordList = null;
		try {
			recordList = this.disciplineRecordService.getListByMap(page.pageToMap());
			page.setPageData(recordList);
		} catch (Exception e) {
			logger.error("分页读取学生违纪信息异常！", e);
		}
	}

	@Override
	public List<Map<String, Object>> getListByMap(Map<String, Object> map) {
		List<Map<String, Object>> recordList = null;
		try {
			recordList = this.disciplineRecordService.getListByMap(map);
		} catch (Exception e) {
			logger.error("读取学生违纪信息异常！", e);
		}
		return recordList;
	}

	@Override
	public List<Map<String, Object>> getClassDisciplineByMap(Map<String, Object> map) {
		List<Map<String, Object>> recordList = null;
		try {
			recordList = this.disciplineRecordService.getClassDisciplineByMap(map);
		} catch (Exception e) {
			logger.error("读取学生违纪信息异常！", e);
		}
		return recordList;
	}

	@Override
	public CommonResult deleteByRecord(long recordId) {
		CommonResult result = new CommonResult();
		StudentDisciplineDataRecord dataRecord = null;
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			StudentDisciplineRecord disciplineRecord = this.disciplineRecordService.getByRecordId(recordId);
			map.put("studentId", disciplineRecord.getStudentId());
			map.put("writeTime", disciplineRecord.getWriteTime());

			if (this.disciplineRecordService.deleteByRecord(recordId)) {
				dataRecord = this.disciplineDataRecordService.getRecordBySelective(map);
				updateAttendanceRecordForDelete(dataRecord);
				result.setIsSuccess(true);
				result.setResultMsg("删除成功！");
			} else {
				result.setResultMsg("删除失败！");
			}

		} catch (Exception e) {
			result.setResultMsg("删除异常！");
			logger.error("学生违纪信息删除异常！", e);
		}
		return result;
	}

	@Override
	public CommonResult deleteByList(List<Long> recordIdList) {
		CommonResult result = new CommonResult();
		List<StudentDisciplineRecord> recordList = null;

		try {
			recordList = this.disciplineRecordService.getByRecordIdList(recordIdList);
			if (this.disciplineRecordService.deleteByList(recordIdList)) {
				updateAttendanceRecordForDeleteList(recordList);
				result.setIsSuccess(true);
				result.setResultMsg("删除成功！");
			} else {
				result.setResultMsg("删除失败！");
			}
		} catch (Exception e) {
			result.setResultMsg("删除异常！");
			logger.error("学生违纪信息删除异常！", e);
		}
		return result;
	}

	@Override
	public CommonResult deleteByWriteTime(Date writeTime) {
		CommonResult result = new CommonResult();
		try {
			if (this.disciplineRecordService.deleteByWriteTime(writeTime)) {
				result.setIsSuccess(true);
				result.setResultMsg("删除成功！");
			} else {
				result.setResultMsg("删除失败！");
			}
		} catch (Exception e) {
			result.setResultMsg("删除异常！");
			logger.error("学生违纪信息删除异常！", e);
		}

		return result;
	}

	@Override
	public boolean isAttendance(long recordId) {
		boolean isAttendance = false;
		try {
			StudentDisciplineRecord disciplineRecord = this.disciplineRecordService.getByRecordId(recordId);
			StudentDiscipline discipline = this.disciplineService.getRecordById(disciplineRecord.getDisciplineId());
			if (Integer.valueOf(discipline.getDisciplineType()).equals(DictionaryEnums.ATTENDANCE_TYPE.getCode())) {
				isAttendance = true;
			}
		} catch (Exception e) {
			logger.error("学生违纪信息删除异常！", e);
		}
		return isAttendance;
	}

	private void updateAttendanceRecordForInsert(StudentDisciplineDataRecord dataRecord) {
		Date writeTime = DateFormatter.parse(DateFormatter.format(dataRecord.getRecord().getWriteTime(), "yyyy-MM"),
				"yyyy-MM");
		StudentAttendanceRecord attendanceRecord = this.attendanceRecordService
				.getBySelective(dataRecord.getRecord().getStudentId(), writeTime);
		if (dataRecord.getRecord().getDisciplineId() == DisciplineEnums.BE_LATE.getCode()) {
			attendanceRecord.setLateNum(attendanceRecord.getLateNum() + 1);
			attendanceRecord.setDeductNum(attendanceRecord.getDeductNum() + dataRecord.getData().getDeductNum());
		} else if (dataRecord.getRecord().getDisciplineId() == DisciplineEnums.LEAVE_EARLY.getCode()) {
			attendanceRecord.setEarlyNum(attendanceRecord.getEarlyNum() + 1);
			attendanceRecord.setDeductNum(attendanceRecord.getDeductNum() + dataRecord.getData().getDeductNum());
		} else if (dataRecord.getRecord().getDisciplineId() == DisciplineEnums.SICK_LEAVE.getCode()) {
			attendanceRecord.setSickNum(attendanceRecord.getSickNum() + 1);
			attendanceRecord.setDeductNum(attendanceRecord.getDeductNum() + dataRecord.getData().getDeductNum());
		} else if (dataRecord.getRecord().getDisciplineId() == DisciplineEnums.MATTER_LEAVE.getCode()) {
			attendanceRecord.setMatterNum(attendanceRecord.getMatterNum() + 1);
			attendanceRecord.setDeductNum(attendanceRecord.getDeductNum() + dataRecord.getData().getDeductNum());
		} else if (dataRecord.getRecord().getDisciplineId() == DisciplineEnums.TRUANT.getCode()) {
			attendanceRecord.setTruantNum(attendanceRecord.getTruantNum() + 1);
			attendanceRecord.setDeductNum(attendanceRecord.getDeductNum() + dataRecord.getData().getDeductNum());
		}

		this.attendanceRecordService.updateRecordSelective(attendanceRecord);
	}

	private void updateAttendanceRecordForUpdate(StudentDisciplineDataRecord oldDataRecord,
			StudentDisciplineDataRecord newDataRecord) {
		Date oldWriteTime = DateFormatter
				.parse(DateFormatter.format(oldDataRecord.getRecord().getWriteTime(), "yyyy-MM"), "yyyy-MM");
		StudentAttendanceRecord attendanceRecord = this.attendanceRecordService
				.getBySelective(oldDataRecord.getRecord().getStudentId(), oldWriteTime);

		if (oldDataRecord.getRecord().getDisciplineId() == DisciplineEnums.BE_LATE.getCode()) {
			attendanceRecord.setLateNum(attendanceRecord.getLateNum() - 1);
			attendanceRecord.setDeductNum(attendanceRecord.getDeductNum() - oldDataRecord.getData().getDeductNum());
		} else if (oldDataRecord.getRecord().getDisciplineId() == DisciplineEnums.LEAVE_EARLY.getCode()) {
			attendanceRecord.setEarlyNum(attendanceRecord.getEarlyNum() - 1);
			attendanceRecord.setDeductNum(attendanceRecord.getDeductNum() - oldDataRecord.getData().getDeductNum());
		} else if (oldDataRecord.getRecord().getDisciplineId() == DisciplineEnums.SICK_LEAVE.getCode()) {
			attendanceRecord.setSickNum(attendanceRecord.getSickNum() - 1);
			attendanceRecord.setDeductNum(attendanceRecord.getDeductNum() - oldDataRecord.getData().getDeductNum());
		} else if (oldDataRecord.getRecord().getDisciplineId() == DisciplineEnums.MATTER_LEAVE.getCode()) {
			attendanceRecord.setMatterNum(attendanceRecord.getMatterNum() - 1);
			attendanceRecord.setDeductNum(attendanceRecord.getDeductNum() - oldDataRecord.getData().getDeductNum());
		} else if (oldDataRecord.getRecord().getDisciplineId() == DisciplineEnums.TRUANT.getCode()) {
			attendanceRecord.setTruantNum(attendanceRecord.getTruantNum() - 1);
			attendanceRecord.setDeductNum(attendanceRecord.getDeductNum() - oldDataRecord.getData().getDeductNum());
		}

		if (newDataRecord.getRecord().getDisciplineId() == DisciplineEnums.BE_LATE.getCode()) {
			attendanceRecord.setLateNum(attendanceRecord.getLateNum() + 1);
			attendanceRecord.setDeductNum(attendanceRecord.getDeductNum() + newDataRecord.getData().getDeductNum());
		} else if (newDataRecord.getRecord().getDisciplineId() == DisciplineEnums.LEAVE_EARLY.getCode()) {
			attendanceRecord.setEarlyNum(attendanceRecord.getEarlyNum() + 1);
			attendanceRecord.setDeductNum(attendanceRecord.getDeductNum() + newDataRecord.getData().getDeductNum());
		} else if (newDataRecord.getRecord().getDisciplineId() == DisciplineEnums.SICK_LEAVE.getCode()) {
			attendanceRecord.setSickNum(attendanceRecord.getSickNum() + 1);
			attendanceRecord.setDeductNum(attendanceRecord.getDeductNum() + newDataRecord.getData().getDeductNum());
		} else if (newDataRecord.getRecord().getDisciplineId() == DisciplineEnums.MATTER_LEAVE.getCode()) {
			attendanceRecord.setMatterNum(attendanceRecord.getMatterNum() + 1);
			attendanceRecord.setDeductNum(attendanceRecord.getDeductNum() + newDataRecord.getData().getDeductNum());
		} else if (newDataRecord.getRecord().getDisciplineId() == DisciplineEnums.TRUANT.getCode()) {
			attendanceRecord.setTruantNum(attendanceRecord.getTruantNum() + 1);
			attendanceRecord.setDeductNum(attendanceRecord.getDeductNum() + newDataRecord.getData().getDeductNum());
		}

		this.attendanceRecordService.updateRecordSelective(attendanceRecord);
	}

	private void updateAttendanceRecordForDelete(StudentDisciplineDataRecord dataRecord) {
		Date writeTime = DateFormatter.parse(DateFormatter.format(dataRecord.getRecord().getWriteTime(), "yyyy-MM"),
				"yyyy-MM");
		StudentAttendanceRecord attendanceRecord = this.attendanceRecordService
				.getBySelective(dataRecord.getRecord().getStudentId(), writeTime);
		if (dataRecord.getRecord().getDisciplineId() == DisciplineEnums.BE_LATE.getCode()) {
			attendanceRecord.setLateNum(attendanceRecord.getLateNum() - 1);
			attendanceRecord.setDeductNum(attendanceRecord.getDeductNum() - dataRecord.getData().getDeductNum());
		} else if (dataRecord.getRecord().getDisciplineId() == DisciplineEnums.LEAVE_EARLY.getCode()) {
			attendanceRecord.setEarlyNum(attendanceRecord.getEarlyNum() - 1);
			attendanceRecord.setDeductNum(attendanceRecord.getDeductNum() - dataRecord.getData().getDeductNum());
		} else if (dataRecord.getRecord().getDisciplineId() == DisciplineEnums.SICK_LEAVE.getCode()) {
			attendanceRecord.setSickNum(attendanceRecord.getSickNum() - 1);
			attendanceRecord.setDeductNum(attendanceRecord.getDeductNum() - dataRecord.getData().getDeductNum());
		} else if (dataRecord.getRecord().getDisciplineId() == DisciplineEnums.MATTER_LEAVE.getCode()) {
			attendanceRecord.setMatterNum(attendanceRecord.getMatterNum() - 1);
			attendanceRecord.setDeductNum(attendanceRecord.getDeductNum() - dataRecord.getData().getDeductNum());
		} else if (dataRecord.getRecord().getDisciplineId() == DisciplineEnums.TRUANT.getCode()) {
			attendanceRecord.setTruantNum(attendanceRecord.getTruantNum() - 1);
			attendanceRecord.setDeductNum(attendanceRecord.getDeductNum() - dataRecord.getData().getDeductNum());
		}

		this.attendanceRecordService.updateRecordSelective(attendanceRecord);
	}

	private void updateAttendanceRecordForDeleteList(List<StudentDisciplineRecord> recordList) {
		Date writeTime = new Date();
		List<Integer> studentIdList = DisciplineDataUtil.getStudentIdList(recordList);
		List<Date> writeTimeSList = DisciplineDataUtil.getWriteTimeList(recordList, "yyyy-MM");
		List<Date> writeTimeLList = DisciplineDataUtil.getWriteTimeList(recordList, "yyyy-MM-dd");
		List<Long> recordIdList = new ArrayList<Long>();
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("studentIdList", studentIdList);
		map.put("writeTimeList", writeTimeLList);
		List<StudentAttendanceRecord> attendanceRecordList = this.attendanceRecordService
				.getByDisciplineRecordListBySelective(studentIdList, writeTimeSList);
		List<StudentDisciplineDataRecord> dataRecordList = this.disciplineDataRecordService.getListBySelective(map);
		for (StudentAttendanceRecord attendanceRecord : attendanceRecordList) {
			for (StudentDisciplineDataRecord dataRecord : dataRecordList) {
				writeTime = DateFormatter.parse(DateFormatter.format(dataRecord.getRecord().getWriteTime(), "yyyy-MM"),
						"yyyy-MM");
				if (attendanceRecord.getStudentId() == dataRecord.getRecord().getStudentId()
						&& attendanceRecord.equals(writeTime)) {
					if (dataRecord.getRecord().getDisciplineId() == DisciplineEnums.BE_LATE.getCode()) {
						attendanceRecord.setLateNum(attendanceRecord.getLateNum() - 1);
						attendanceRecord
								.setDeductNum(attendanceRecord.getDeductNum() - dataRecord.getData().getDeductNum());
					} else if (dataRecord.getRecord().getDisciplineId() == DisciplineEnums.LEAVE_EARLY.getCode()) {
						attendanceRecord.setEarlyNum(attendanceRecord.getEarlyNum() - 1);
						attendanceRecord
								.setDeductNum(attendanceRecord.getDeductNum() - dataRecord.getData().getDeductNum());
					} else if (dataRecord.getRecord().getDisciplineId() == DisciplineEnums.SICK_LEAVE.getCode()) {
						attendanceRecord.setSickNum(attendanceRecord.getSickNum() - 1);
						attendanceRecord
								.setDeductNum(attendanceRecord.getDeductNum() - dataRecord.getData().getDeductNum());
					} else if (dataRecord.getRecord().getDisciplineId() == DisciplineEnums.MATTER_LEAVE.getCode()) {
						attendanceRecord.setMatterNum(attendanceRecord.getMatterNum() - 1);
						attendanceRecord
								.setDeductNum(attendanceRecord.getDeductNum() - dataRecord.getData().getDeductNum());
					} else if (dataRecord.getRecord().getDisciplineId() == DisciplineEnums.TRUANT.getCode()) {
						attendanceRecord.setTruantNum(attendanceRecord.getTruantNum() - 1);
						attendanceRecord
								.setDeductNum(attendanceRecord.getDeductNum() - dataRecord.getData().getDeductNum());
					}
				}
			}
			recordIdList.add(attendanceRecord.getRecordId());
		}
		this.attendanceRecordService.deleteByRecordIdList(recordIdList);
		this.attendanceRecordService.insertByList(attendanceRecordList);
	}
}
